<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>

</html>
<script>
    // 是把接收多个参数的函数 变成接收一个单一参数(最初函数的第一个参数)的函数   
    // 并且返回接收剩余参数的新函数的技术   
    // 实现参数复用(闭包和高阶函数的特性),延迟运行  


    // demo1 
    // // 未柯里化  
    // function getUrl(protocpl, hostname, pathname) {
    //     return `${protocpl}://${hostname}/${pathname}`
    // }
    // console.log(getUrl("https", "taobao.com", "123.html"));
    // // https://taobao.com/123.html

    // // 部分柯里化 
    // function getUrl_(a) {
    //     return (b, c) => {
    //         return `${a}://${b}/${c}`
    //     }
    // }
    // const join = getUrl_("http")   // 这里的节点实现了复用   
    // console.log(join('jindong', '123.html'));
    // // http://jindong/123.html
    // console.log(join('ali', '456.html'));
    // // http://ali/456.html

    // // 柯里化的 函数  
    // function getUrlAll(a) {
    //     return (b) => {
    //         return (c) => {
    //             return `${a}//${b}/${c}`
    //         }
    //     }
    // }
    // const j1 = getUrlAll("https");
    // const j2 = j1("cdd")
    // const j3 = j2("111111111111.html")
    // console.log(j1);
    // console.log(j2);
    // console.log(j3);   //  https//cdd/111111111111.html

    // const j4 = getUrl('1111')
    // console.log(j4);   //  1111://undefined/undefined


    // 通用的柯里化函数  


    function cury(fn, ...arg) {
        // 如果参数够了直接执行 把传入的参数以此传入fn
        if(arg.length >= fn.length) {
         return fn(...arg)
        }
        // 否则 需要合并参数 递归调用柯里化函数
        return function(...rest){
           return cury(fn,...arg,...rest)
        }
    }

    function add(x,y,z){
        console.log(x+y+z);
    }
    
    // console.log(cury(add)(1)(2)(3));
    console.log(cury(add)(1,2)(3));
    // console.log(cury(add,1)(2)(3));-

    function getUrl(a,b,c){
        return `${a}://${b}/${c}`
    }
    console.log(cury(getUrl)('http','cdd',"xxx.html"));  
    // console.log();
     // http://cdd/xxx.html



















  //函数柯里化 
    //柯里化是将具有多个参数的函数转换为每个只有一个参数的函数序列的过程。
    //Currying 以数学家Haskell Curry 的名字命名。通过应用柯里化，n 元函数将其变成一元函数。

    // 让我们举一个 n-ary 函数的例子，以及它如何变成一个柯里化函数
    // const multiArgFunction = (a, b, c) => a + b + c;
    // console.log(multiArgFunction(1,2,3));// 6
    // const curryUnaryFunction = a => b => c => a + b + c;
    // curryUnaryFunction (1);             // return a function: b => c =>  1 + b + c
    // curryUnaryFunction (1) (2);         // return a function: c => 3 + c
    // curryUnaryFunction (1) (2) (3);     // return 数字 6
    //Curried 函数对于提高代码复用性和函数组合非常有用。
</script>